%{
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "trie.h"

//TRIE donde voy a guardar los nombres definidos
Trie* nombres_definidos;

%}
%union{
    int intval;
    float floatval;
    char* strval;
}	

%token DEFINE MOVE SCALE ROTATE REPEAT CIRCLE BOX NAME INT FLOAT
%type <intval> INT
%type <floatval> FLOAT
%type <strval> NAME
%type <floatval> num

%error_verbose

%%
entrada : /*lambda*/
	| entrada grafico
;
grafico : BOX num num 
			{printf("gsave %g %g scale box grestore\n", $2, $3);}
	| CIRCLE num 
			{printf("gsave %g %g scale circ grestore\n", $2, $2);}
	| DEFINE NAME 
			{ printf("/%s {\n",$2);
			insert_in_Trie(nombres_definidos, $2);}
		grafico	
			{printf("} def\n");}
	| NAME	
		{if (belongs_to_Trie(nombres_definidos, $1))
			printf("%s\n", $1);
		 else {
			char *m = (char*)malloc(sizeof(char)*(strlen($1)+25));
			strcpy(m,"'");
			strcpy(m+1,$1);
			yyerror(strcat(m,"' no esta definido"));
			free(m);
			YYERROR; } 
		}
	| MOVE num num
			{printf("gsave\n%g %g translate ", $2, $3);}
		grafico
			{printf("\ngrestore\n");}
	| SCALE num num
			{printf("gsave\n%g %g scale ", $2, $3);}
		grafico
			{printf("\ngrestore\n");}
	| ROTATE num
			{printf("gsave\n%g rotate ", $2);}
		grafico
			{printf("\ngrestore\n");}
	| REPEAT INT
			{if($2 < 1){yyerror("La cantidad de repeticiones de "
                                "repeat debe ser positiva"); YYERROR;}
			  printf("%d {\ngsave\n", $2);}	
		num num grafico 
			{printf("grestore\n%g %g translate } repeat\n",$4,$5);}
	| '(' entrada grafico ')'
			{ }	
;
num	: INT				{$$ = (float)$1}
	| FLOAT				{$$ = $1}
;
%%

extern int row, col, yyleng;

int main() {
	//Inicializo el TRIE
	nombres_definidos = new_Trie();    
	
	printf("%%Prologo. Definicion de box y circle.\n"
	"\n"
	"5 dict begin\n"
	"/box {\n"
	"  0 0 moveto 0 1 lineto 1 1 lineto 1 0 lineto closepath fill\n"
	"} def\n"
	"/circ {\n"
	"  0 0 1 0 360 arc closepath fill\n"
	"} def\n"
	"\n"
	"%%Fin Prologo. Comienzo grafico.\n"
	"\n");

    yyparse();

    printf("\n"
	"%%Fin grafico.\n"
	"\n"
	"end\n"
	"showpage\n");

	delete_Trie(nombres_definidos);
}

yyerror (char *s)
{
  //avisa tambien la fila y columna donde ocurrio
  fprintf (stderr, "At row %d, column %d: %s\n", row, col - yyleng, s);
}

int yywrap()  
{  
   return 1;  
} 

